# coding=utf-8

from string import Template
from typing import List
from parse.sdb_parser import Signal, TXGroup
from utils.payload import  VhalType

from utils.util import writeFile

signal_read_property_cpp=Template(
"""
#include "PlatformProperty.h"

TRANSMIT_READ_PROPERTY(${properyName},${propType}) {
    builder.area(VehicleArea::GLOBAL)
        .initValue([](){
                return ${initValue};
        })
        .immutableStatus(PropertyStatus::Active)
        .withValueBySignals([]([[maybe_unused]]const ${propType}& last){
${impl}
        },ecarx::transfer::SignalRX::${signalName});
}
"""
)

signal_read_base_type_parse=Template(
"""
                auto signal=SIGNAL.get${signalName}();
                return signal;
"""
)

signal_read_enum_type_parse=Template(
"""
                auto signal=SIGNAL.get${signalName}();
                return ${propType}((int32_t)signal);
"""
)

write_property_cpp=Template(
"""
#include <apvp.pb.h>
#include "PlatformProperty.h"

TRANSMIT_WRITE_PROPERTY(${properyName},${propType}) {
    builder
        .area(VehicleArea::GLOBAL)
        .immutableStatus(PropertyStatus::Active)
        .onSetProperty([](const ${propType}& value) {
${impl}
        });
}
"""
)

templete_base_type_parse=Template(
"""
                SIGNAL.set${signalName}(value);
"""
)

templete_enum_type_parse=Template(
"""
                SIGNAL.set${signalName}(sdb::${propType}((int32_t)value));
"""
)

templete_struct_parse=Template(
"""
                ecarx::transfer::${struct_Type} structObj;
${members}       
                SIGNAL.set${signalName}(structObj);
"""
)

templete_struct_member_parse=Template(
"""                structObj.${member}=(${convert_type})value.${protoMember}();"""
)


def gen_SignalDirectTransmitPropertyImpl(signals:List[Signal],txSignals:List[TXGroup]):
    for signal in signals:
        if signal.getVhalType() == VhalType.float_t:
            writeFile("../vhal_platform/directTransmit", "{}.cpp".format(signal.name),
                        lambda file: file.write(signal_read_property_cpp.substitute(
                            properyName=signal.name,
                            propType="float",
                            initValue="0f",
                            impl=signal_read_base_type_parse.substitute(
                                    signalName=signal.name
                                ),
                            signalName=signal.name
                        )))
        else:
            if signal.getEncodeType() is not None:
                writeFile("../vhal_platform/directTransmit", "{}.cpp".format(signal.name),
                            lambda file: file.write(signal_read_property_cpp.substitute(
                                properyName=signal.name,
                                propType=signal.getEncodeType().getTypeName(),
                                initValue="{}(-1)".format(signal.getEncodeType().getTypeName()),
                                impl=signal_read_enum_type_parse.substitute(
                                        signalName=signal.name,
                                        propType=signal.getEncodeType().getTypeName()
                                    ),
                                signalName=signal.name
                            )))
            else:
                writeFile("../vhal_platform/directTransmit", "{}.cpp".format(signal.name),
                            lambda file: file.write(signal_read_property_cpp.substitute(
                                properyName=signal.name,
                                propType="int32_t",
                                initValue="-1",
                                impl=signal_read_base_type_parse.substitute(
                                        signalName=signal.name,
                                    ),
                                signalName=signal.name
                            )))

    for txSignal in txSignals:
        if txSignal.getVhalType() == VhalType.float_t:
            writeFile("../vhal_platform/directTransmit", "{}.cpp".format(txSignal.name),
                        lambda file: file.write(write_property_cpp.substitute(
                            properyName=txSignal.name,
                            propType="float",
                            impl=templete_base_type_parse.substitute(
                                    signalName=txSignal.name
                                )
                        )))
        elif txSignal.getVhalType() == VhalType.int32_t:
            signal=txSignal.signals[0]
            if signal.hasEnum():
                writeFile("../vhal_platform/directTransmit", "{}.cpp".format(txSignal.name),
                            lambda file: file.write(write_property_cpp.substitute(
                                properyName=txSignal.name,
                                propType=signal.getEncodeType().getTypeName(),
                                impl=templete_enum_type_parse.substitute(
                                        signalName=txSignal.name,
                                        propType = signal.getEncodeType().getTypeName(),
                                    )
                            )))
            else:
                writeFile("../vhal_platform/directTransmit", "{}.cpp".format(txSignal.name),
                        lambda file: file.write(write_property_cpp.substitute(
                            properyName=txSignal.name,
                            propType="int32_t",
                            impl=templete_base_type_parse.substitute(
                                    signalName=txSignal.name
                                )
                        )))
        else:
            #信号组
            members=[]
            for signal in txSignal.signals:
                members.append(templete_struct_member_parse.substitute(
                        member=signal.getVariableName(True,txSignal.isSingle()),
                        protoMember = signal.getVariableName(True,txSignal.isSingle()).lower(),
                        convert_type=signal.getValueType().name

                    ))
            writeFile("../vhal_platform/directTransmit", "{}.cpp".format(txSignal.name),
                        lambda file: file.write(write_property_cpp.substitute(
                            properyName=txSignal.name,
                            propType="proto::ipcp::"+txSignal.name,
                            impl=templete_struct_parse.substitute(
                                    signalName=txSignal.name,
                                    struct_Type=txSignal.name,
                                    members="\n".join(members)
                                )
                        )))
    
           
                

    